<?php
/**
 * Created by PhpStorm.
 * User: steven
 * Date: 2017/11/21
 * Time: 下午10:15
 */

namespace app\api\service;


use app\lib\exception\TokenException;
use app\lib\exception\WeChatException;
use think\Exception;
use app\api\model\User as UserModel;

class UserToken extends Token {


    protected $code;
    protected $wxAppID;
    protected $wxAppSecret;
    protected $wxLoginUrl;

    public function __construct($code) {
        $this->$code       = $code;
        $this->wxAppID     = config('wx.app_id');
        $this->wxAppSecret = config('wx.app_secret');
        $this->wxLoginUrl  = sprintf(config('wx.login_url'),$this->wxAppID,$this->wxAppSecret,$this->code);
    }

    public function get(){
        $result   = curl_get($this->wxLoginUrl);

        // 把json字符串变成一个数组
        $wxResult = json_decode($result,true);

        if(empty($wxResult)){
            throw new Exception('获取session_key及openID时异常，微信内部错误');
        }else{
            $loginFail = array_key_exists('errcode',$wxResult);
            if($loginFail){
                $this->processLoginError($wxResult);
            }else{
                $this->grantToken($wxResult);
            }
        }
    }

    private function processLoginError($wxResult){
        throw new WeChatException([
            'msg'       => $wxResult['errmsg'],
            'errorCode' => $wxResult['errcode']
        ]);
    }

    private function newUser($openid){
        $user = UserModel::create([
           'openid' => $openid
        ]);
        return $user->id;
    }

    private function saveToCache($cachedValue){

        $key       = self::generateToken();
        $value     = json_decode($cachedValue);
        $expire_in = config('setting.token_expire_in');

        $request   = cache($key,$value,$expire_in);
        if(!$request){
            throw new TokenException([
               'msg'       => '服务器缓存异常',
               'errorCode' => 10005
            ]);
        }

        return $key;
    }

    private function prepareCachedValue($wxResult,$uid){
        $cachedValue          = $wxResult;
        $cachedValue['uid']   = $uid;
        $cachedValue['scope'] = 16;
        return $cachedValue;
    }

    private function grantToken($wxResult){
        // 拿到openid
        // 去数据库看一下，openid已经生成了
        // 如果存在则不处理，如果不存在就生成一条user记录
        // 生成令牌，准备缓存数据，写入缓存
        // 把令牌返回到客户端
        // key:令牌
        // value:wxResult,uid,scope
        $openid = $wxResult['openid'];
        $user   = UserModel::getByOpenID($openid);
        if($user){
            $uid = $user->id;
        }else{
            $uid = $this->newUser($openid);
        }

        $cachedValue = $this->prepareCachedValue($wxResult,$uid);
        $token       = $this->saveToCache($cachedValue);
        return $token;
    }
}